﻿using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Interop;
using MoonSharp.Interpreter.Loaders;
using System;
using System.Collections;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEngine;

public class LuaComponent : MonoBehaviour
{
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cache4;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cache5;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cache6;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cache7;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cache8;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cache9;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cacheA;
    [CompilerGenerated]
    private static Func<DynValue, object> <>f__am$cacheB;
    [CompilerGenerated]
    private static Action<string> <>f__am$cacheC;
    [CompilerGenerated]
    private static Func<DynValue, string> <>f__am$cacheD;
    [Multiline]
    public string code;
    public string scriptFileName;
    private const string scriptFileNameTableKey = "__scriptFileName";
    private DynValue yieldfunc;

    static LuaComponent()
    {
        if (<>f__am$cache4 == null)
        {
            <>f__am$cache4 = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__9E);
        }
        SetConverter(DataType.Function, typeof(IEnumerator), <>f__am$cache4);
        if (<>f__am$cache5 == null)
        {
            <>f__am$cache5 = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__9F);
        }
        SetConverter(DataType.Function, typeof(Action), <>f__am$cache5);
        if (<>f__am$cache6 == null)
        {
            <>f__am$cache6 = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__A0);
        }
        SetConverter(DataType.String, typeof(string[]), <>f__am$cache6);
        if (<>f__am$cache7 == null)
        {
            <>f__am$cache7 = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__A1);
        }
        SetConverter(DataType.Table, typeof(string[]), <>f__am$cache7);
        if (<>f__am$cache8 == null)
        {
            <>f__am$cache8 = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__A2);
        }
        SetConverter(DataType.Table, typeof(Vector2), <>f__am$cache8);
        if (<>f__am$cache9 == null)
        {
            <>f__am$cache9 = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__A3);
        }
        SetConverter(DataType.Table, typeof(Vector3), <>f__am$cache9);
        if (<>f__am$cacheA == null)
        {
            <>f__am$cacheA = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__A4);
        }
        SetConverter(DataType.Table, typeof(Color32), <>f__am$cacheA);
        if (<>f__am$cacheB == null)
        {
            <>f__am$cacheB = new Func<DynValue, object>(LuaComponent.<LuaComponent>m__A5);
        }
        SetConverter(DataType.String, typeof(System.Type), <>f__am$cacheB);
        UserData.RegistrationPolicy = InteropRegistrationPolicy.Automatic;
        UserData.RegisterExtensionType(typeof(MoonSharpExtension), InteropAccessMode.Default);
        UserData.RegisterType<LuaComponent>(InteropAccessMode.Default, null);
        UserData.RegisterType<System.Type>(InteropAccessMode.Default, null);
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__9E(DynValue v)
    {
        object[] args = new object[] { v };
        return v.Function.CreateCoroutine(args);
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__9F(DynValue v)
    {
        return v.Function.ToAction();
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__A0(DynValue v)
    {
        return new string[] { v.String };
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__A1(DynValue v)
    {
        if (<>f__am$cacheD == null)
        {
            <>f__am$cacheD = x => x.String;
        }
        return v.Table.Values.Select<DynValue, string>(<>f__am$cacheD).ToArray<string>();
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__A2(DynValue v)
    {
        return v.ToVector2();
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__A3(DynValue v)
    {
        return v.ToVector3();
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__A4(DynValue v)
    {
        return v.ToColor32();
    }

    [CompilerGenerated]
    private static object <LuaComponent>m__A5(DynValue v)
    {
        return GetType(v.String);
    }

    [CompilerGenerated]
    private static string <LuaComponent>m__A7(DynValue x)
    {
        return x.String;
    }

    public Component AddComponent(System.Type type)
    {
        return base.gameObject.AddComponent(type);
    }

    protected virtual void Awake()
    {
        if (!string.IsNullOrEmpty(this.code))
        {
            this.DoString(this.code);
        }
        if (!string.IsNullOrEmpty(this.scriptFileName))
        {
            this.DoFile(this.scriptFileName);
        }
        this.script.CallFunctionIfExists("Awake", new object[0]);
    }

    public bool ContainsFile(string fileName)
    {
        return (LuaComponentUtility.GetScriptAsset(fileName) != null);
    }

    public bool ContainsFunction(string name)
    {
        DynValue value2 = this.script.Globals.Get(name);
        return ((value2 != null) && (value2.Function != null));
    }

    public static T Create<T>(GameObject go, string scriptFileName) where T: LuaComponent
    {
        go.SetActive(false);
        T local = go.AddComponent<T>();
        local.scriptFileName = scriptFileName;
        go.SetActive(true);
        return local;
    }

    private static Script CreateScript()
    {
        Script script = new Script {
            Options = { UseLuaErrorLocations = true }
        };
        GameScriptLoader loader2 = new GameScriptLoader();
        loader2.ModulePaths = new string[] { "?", "?.lua" };
        GameScriptLoader loader = loader2;
        script.Options.ScriptLoader = loader;
        ((ScriptLoaderBase) script.Options.ScriptLoader).IgnoreLuaPathGlobal = true;
        if (<>f__am$cacheC == null)
        {
            <>f__am$cacheC = delegate (string s) {
                Debug.Log(s);
            };
        }
        script.Options.DebugPrint = <>f__am$cacheC;
        return script;
    }

    public void DoFile(string scriptFileName)
    {
        StreamingAsset scriptAsset = LuaComponentUtility.GetScriptAsset(scriptFileName);
        if (scriptAsset == null)
        {
            object[] args = new object[] { scriptFileName };
            Debug.LogErrorFormat("Could not find script '{0}'", args);
        }
        else
        {
            this.scriptFileName = scriptFileName;
            string text = scriptAsset.text;
            this.DoString(text);
        }
    }

    public void DoString(string code)
    {
        try
        {
            if (this.script == null)
            {
                this.script = CreateScript();
                this.script.SetProperty("this", this);
                this.script.SetProperty("using", new Func<string, DynValue>(this.Using));
                this.script.SetProperty("typeof", new Func<string, System.Type>(this.TypeOf));
                this.script.SetProperty("GetComponent", new Func<System.Type, Component>(this.GetComponent));
                this.script.SetProperty("AddComponent", new Func<System.Type, Component>(this.AddComponent));
                this.script.SetProperty("RequireComponent", new Func<System.Type, Component>(this.RequireComponent));
                this.script.SetProperty("__scriptFileName", this.scriptFileName);
                this.yieldfunc = this.script.Globals.Get("coroutine").Table.Get("yield");
                this.OnCreateScript(this.script);
            }
            DynValue function = this.script.LoadString(code, null, this.scriptFileName);
            this.script.Call(function);
        }
        catch (InterpreterException exception)
        {
            throw exception.GetDecoratedException<InterpreterException>(this.script);
        }
    }

    private static System.Type GetType(string typeName)
    {
        if (typeName.Contains("."))
        {
            return Types.GetType(typeName, typeName.Substring(0, typeName.LastIndexOf('.')));
        }
        System.Type type = Types.GetType(typeName, "Assembly-CSharp-firstpass");
        if (type == null)
        {
            type = Types.GetType(typeName, "Assembly-CSharp");
        }
        return type;
    }

    public DynValue GetValue(string key)
    {
        return this.script.Globals.Get(key);
    }

    protected virtual void OnCreateScript(Script script)
    {
    }

    public Component RequireComponent(System.Type type)
    {
        Component component = base.gameObject.GetComponent(type);
        if (component == null)
        {
            return base.gameObject.AddComponent(type);
        }
        return component;
    }

    public static void SetConverter(DataType dataType, System.Type clrType, Func<DynValue, object> converter)
    {
        Script.GlobalOptions.CustomConverters.SetScriptToClrCustomConversion(dataType, clrType, converter);
    }

    protected virtual void Start()
    {
    }

    private System.Type TypeOf(string typeName)
    {
        System.Type type = GetType(typeName);
        if (type == null)
        {
            object[] args = new object[] { typeName };
            Debug.LogErrorFormat("Cound not find type '{0}'", args);
            return null;
        }
        return type;
    }

    private DynValue Using(string typeName)
    {
        System.Type t = GetType(typeName);
        if (t == null)
        {
            object[] args = new object[] { typeName };
            Debug.LogErrorFormat("Cound not find type '{0}'", args);
            return null;
        }
        return UserData.CreateStatic(t);
    }

    public void Yield(UnityEngine.Coroutine coroutine)
    {
        object[] args = new object[] { coroutine };
        this.script.Call(this.yieldfunc, args);
    }

    private MonoBehaviour coroutineHandler
    {
        get
        {
            return this;
        }
    }

    public Script script { get; private set; }

    private object thisObject
    {
        get
        {
            return this;
        }
    }

    public class GameScriptLoader : ScriptLoaderBase
    {
        public override object LoadFile(string scriptName, Table globalContext)
        {
            StreamingAsset scriptAsset = LuaComponentUtility.GetScriptAsset(scriptName);
            if (scriptAsset == null)
            {
                scriptAsset = LuaComponentUtility.GetScriptAsset(PathUtility.ChangeFileName(globalContext.Get("__scriptFileName").String, scriptName));
            }
            if (scriptAsset == null)
            {
                object[] args = new object[] { scriptName };
                Debug.LogErrorFormat("Could not find script '{0}'", args);
                return string.Empty;
            }
            return scriptAsset.text;
        }

        public override bool ScriptFileExists(string path)
        {
            return true;
        }
    }
}

